package util;

import java.util.Arrays;
import java.util.List;

public class ByteArrayUtil {

    public static byte[] hexStringToBytes(String hex) {

        if(hex.length() % 2 != 0) hex = hex + "0";

        byte[] ret = new byte[hex.length() / 2];

        for(int i = 0, j = 1; i < ret.length && j < ret.length; i += 2, j += 2) {

            ret[i >>> 1] = (byte) ((Byte.parseByte("" + hex.charAt(i)) << 4) & Byte.parseByte("" + hex.charAt(j)));
        }

        return ret;
    }

    public static byte[] concat(byte[] a, byte[] b) {

        if(a == null) return b;

        if(b == null) return a;

        byte[] tmp = new byte[a.length + b.length];

        System.arraycopy(a, 0, tmp, 0, a.length);

        System.arraycopy(b, 0, tmp, a.length, b.length);

        return tmp;
    }

    public static byte[] concat(byte[] a, byte[] ... bss) {

        byte[] tmp = new byte[flattenArrayLength(bss) + a.length];

        System.arraycopy(a, 0, tmp, 0, a.length);

        for(int i = 0, pos = a.length; i < bss.length; pos += bss[i].length, ++i) {

            System.arraycopy(bss[i], 0, tmp, pos, bss[i].length);
        }

        return tmp;
    }

    public static byte[] flatten(List<byte[]> params) {

        byte[] tmp = new byte[flattenListLength(params)];

        for(int i = 0, pos = 0; i < params.size(); pos += params.get(i).length, ++i) {

            System.arraycopy(params.get(i), 0, tmp, pos, params.get(i).length);
        }

        return tmp;
    }

    private static int flattenArrayLength(byte[][] arr) {

        int totalLength = 0;

        for (byte[] bs : arr) totalLength += bs.length;

        return totalLength;
    }

    private static int flattenListLength(List<byte[]> list) {

        int totalLength = 0;

        for (byte[] bs : list) totalLength += bs.length;

        return totalLength;
    }

    public static byte[] unBoxed(Byte[] bs) {

        byte[] tmp = new byte[bs.length];

        for(int i = 0; i < tmp.length; ++i) tmp[i] = bs[i];

        return tmp;
    }

    public static byte[] asByteArray(byte ... bs) {

        return bs;
    }
}
